﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace iNet.Media.Imaging
{
	/// <summary>
	/// 影像中繼資料介面。
	/// </summary>
	public interface IImageMetadata : IMetadata
	{
		/// <summary>
		/// 取得或設定光圈值。
		/// </summary>
		double? Aperture { get; set; }
		/// <summary>
		/// 取得或設定相機製造商。
		/// </summary>
		string CameraManufacturer { get; set; }
		/// <summary>
		/// 取得或設定相機型號。
		/// </summary>
		string CameraModel { get; set; }
		/// <summary>
		/// 取得或設定曝光補償值。
		/// </summary>
		double? ExposureCompensation { get; set; }
		/// <summary>
		/// 取得或設定曝光程式。
		/// </summary>
		ExposureProgram? ExposureProgram { get; set; }
		/// <summary>
		/// 取得或設定閃光燈製造商。
		/// </summary>
		string FlashManufacturer { get; set; }
		/// <summary>
		/// 取得或設定閃光燈型號。
		/// </summary>
		string FlashModel { get; set; }
		/// <summary>
		/// 取得或設定實際焦距，單位為毫米 (mm)。
		/// </summary>
		double? FocalLength { get; set; }
		/// <summary>
		/// 取得或設定等效焦距，單位為毫米 (mm)。
		/// </summary>
		double? FocalLengthIn35mmFilm { get; set; }
		/// <summary>
		/// 取得或設定影像的地理座標。
		/// </summary>
		GeoCoordinate GeoCoordinate { get; set; }
		/// <summary>
		/// 取得或設定閃光燈狀態。
		/// </summary>
		FlashState? FlashState { get; set; }
		/// <summary>
		/// 取得或設定 ISO 值。
		/// </summary>
		int? ISO { get; set; }
		/// <summary>
		/// 取得或設定鏡頭製造商。
		/// </summary>
		string LensManufacturer { get; set; }
		/// <summary>
		/// 取得或設定鏡頭型號。
		/// </summary>
		string LensModel { get; set; }
		/// <summary>
		/// 取得或設定影像方向。
		/// </summary>
		ImageOrientation? Orientation { get; set; }
		/// <summary>
		/// 取得或設定影像中的人員資訊。
		/// </summary>
		PersonRegion[] People { get; set; }
		/// <summary>
		/// 取得或設定快門速度。
		/// </summary>
		URational? ShutterSpeed { get; set; }
	}
	#region ExposureProgram
	/// <summary>
	/// 表示曝光程式。
	/// </summary>
	public enum ExposureProgram
	{
		/// <summary>
		/// 手動調整。
		/// </summary>
		Manual = 1,
		/// <summary>
		/// 一般模式。
		/// </summary>
		NormalProgram = 2,
		/// <summary>
		/// 光圈優先。
		/// </summary>
		AperturePriority = 3,
		/// <summary>
		/// 快門優先。
		/// </summary>
		ShutterPriority = 4,
		/// <summary>
		/// 創意模式。
		/// </summary>
		CreativeProgram = 5,
		/// <summary>
		/// 運動模式。
		/// </summary>
		ActionProgram = 6,
		/// <summary>
		/// 人像模式。
		/// </summary>
		PortraitMode = 7,
		/// <summary>
		/// 風景模式。
		/// </summary>
		LandscapeMode = 8,
	}
	#endregion
	#region FlashMode
	/// <summary>
	/// 表示閃光燈模式。
	/// </summary>
	public enum FlashMode
	{
		/// <summary>
		/// 關閉。
		/// </summary>
		Off,
		/// <summary>
		/// 開啟。
		/// </summary>
		On,
		/// <summary>
		/// 自動。
		/// </summary>
		Auto,
	}
	#endregion
	#region FlashRetuenState
	/// <summary>
	/// 表示閃光燈反射狀態。
	/// </summary>
	public enum FlashRetuenState
	{
		/// <summary>
		/// 未偵測到反射。
		/// </summary>
		NotDetected,
		/// <summary>
		/// 已偵測到反射。
		/// </summary>
		Detected,
	}
	#endregion
	#region FlashState
	/// <summary>
	/// 表示閃光燈的狀態。
	/// </summary>
	public struct FlashState
	{
		#region HasRedEyeReduction
		/// <summary>
		/// 取得或設定是否已開啟去紅眼功能。
		/// </summary>
		public bool HasRedEyeReduction { get; set; }
		#endregion
		#region FromExifFlashState
		/// <summary>
		/// 使用 EXIF 的閃光燈狀態建立 FlashState 結構。
		/// </summary>
		/// <param name="state">EXIF 閃光燈狀態值。</param>
		/// <returns>FlashState 結構。</returns>
		public static FlashState FromExifFlashState(int state)
		{
			//取得擊發狀態
			FlashState flashState = new FlashState();
			flashState.IsFired = ((state & 0x1) == 1);

			//取得反光狀態
			if ((state & 0x6) == 0x6)
				flashState.ReturnState = FlashRetuenState.Detected;
			else
				flashState.ReturnState = FlashRetuenState.NotDetected;

			//取得模式
			switch(state & 0x18)
			{
				case 0x18:
					flashState.Mode = FlashMode.Auto;
					break;
				case 0x8:
					flashState.Mode = FlashMode.On;
					break;
				default:
					flashState.Mode = FlashMode.Off;
					break;
			}

			//取得閃光燈支援狀態
			flashState.IsSupported = ((state & 0x20) == 0);

			//取得去紅眼狀態
			flashState.HasRedEyeReduction = ((state & 0x40) == 0x40);

			//完成
			return flashState;
		}
		#endregion
		#region FromXmpFlashState
		/// <summary>
		/// 使用 XMP 的閃光燈狀態建立 FlashState 結構。
		/// </summary>
		/// <param name="value">XMP 閃光燈狀態值。</param>
		/// <returns>FlashState 結構。</returns>
		/// <exception cref="ArgumentNullException">value 為 Null (Visual Basic 為 Nothing)。</exception>
		public static FlashState FromXmpFlashState(Xmp.FlashXmpPropertyValue value)
		{
			//確認參數
			if (value == null)
				throw new ArgumentNullException("value");

			//取得擊發狀態
			FlashState flashState = new FlashState();
			flashState.IsFired = (value.Fired != null && value.Fired.Value);

			//取得反光狀態
			if (value.Return != null && value.Return.Value == 0x3)
				flashState.ReturnState = FlashRetuenState.Detected;
			else
				flashState.ReturnState = FlashRetuenState.NotDetected;

			//取得模式
			if (value.Mode != null)
			{
				switch (value.Mode.Value)
				{
					case 0x3:
						flashState.Mode = FlashMode.Auto;
						break;
					case 0x1:
						flashState.Mode = FlashMode.On;
						break;
					default:
						flashState.Mode = FlashMode.Off;
						break;
				}
			}
			else
				flashState.Mode = FlashMode.Off;

			//取得閃光燈支援狀態
			flashState.IsSupported = (value.Function != null && value.Function.Value);

			//取得去紅眼狀態
			flashState.HasRedEyeReduction = (value.RedEyeMode != null && value.RedEyeMode.Value);

			//完成
			return flashState;
		}
		#endregion
		#region IsFired
		/// <summary>
		/// 取得或設定閃光燈是否擊發。
		/// </summary>
		public bool IsFired { get; set; }
		#endregion
		#region IsSupported
		/// <summary>
		/// 取得或設定是否支援閃光燈功能。
		/// </summary>
		public bool IsSupported { get; set; }
		#endregion
		#region Mode
		/// <summary>
		/// 取得或設定閃光燈模式。
		/// </summary>
		public FlashMode Mode { get; set; }
		#endregion
		#region ReturnState
		/// <summary>
		/// 取得或設定閃光燈反射狀態。
		/// </summary>
		public FlashRetuenState ReturnState { get; set; }
		#endregion
		#region ToExifFlashState
		/// <summary>
		/// 取得對應的 EXIF 閃光燈狀態值。
		/// </summary>
		/// <returns>EXIF 閃光燈狀態值。</returns>
		public int ToExifFlashState()
		{
			//取得擊發狀態
			int state = (this.IsFired ? 0x1 : 0x0);

			//取得反光狀態
			switch(this.ReturnState)
			{
				case FlashRetuenState.Detected:
					state |= 0x6;
					break;
				default:
					state |= 0x4;
					break;
			}

			//取得模式
			switch(this.Mode)
			{
				case FlashMode.Auto:
					state |= 0x18;
					break;
				case FlashMode.On:
					state |= 0x8;
					break;
				default:
					state |= 0x10;
					break;
			}

			//取得閃光燈支援狀態
			if (!this.IsSupported)
				state |= 0x20;

			//取得去紅眼狀態
			if(this.HasRedEyeReduction)
				state |= 0x40;

			//完成
			return state;
		}
		#endregion
		#region ToXmpFlashState
		/// <summary>
		/// 取得對應的 XMP 閃光燈狀態值。
		/// </summary>
		/// <returns>XMP 閃光燈狀態值。</returns>
		public Xmp.FlashXmpPropertyValue ToXmpFlashState()
		{
			//取得擊發狀態
			Xmp.FlashXmpPropertyValue flashValue = new Xmp.FlashXmpPropertyValue();
			flashValue.Fired = new Xmp.BooleanXmpPropertyValue(this.IsFired);

			//取得反光狀態
			switch (this.ReturnState)
			{
				case FlashRetuenState.Detected:
					flashValue.Return = new Xmp.IntegerXmpPropertyValue(0x3);
					break;
				default:
					flashValue.Return = new Xmp.IntegerXmpPropertyValue(0x2);
					break;
			}

			//取得模式
			switch (this.Mode)
			{
				case FlashMode.Auto:
					flashValue.Mode = new Xmp.IntegerXmpPropertyValue(0x3);
					break;
				case FlashMode.On:
					flashValue.Mode = new Xmp.IntegerXmpPropertyValue(0x1);
					break;
				default:
					flashValue.Mode = new Xmp.IntegerXmpPropertyValue(0x2);
					break;
			}

			//取得閃光燈支援狀態
			flashValue.Function = new Xmp.BooleanXmpPropertyValue(this.IsSupported);

			//取得去紅眼狀態
			flashValue.RedEyeMode = new Xmp.BooleanXmpPropertyValue(this.HasRedEyeReduction);

			//完成
			return flashValue;
		}
		#endregion
	}
	#endregion
	#region ImageOrientation
	/// <summary>
	/// 表示影像的方向。
	/// </summary>
	public enum ImageOrientation
	{
		/// <summary>
		/// 正常方向。
		/// </summary>
		Rotate0 = 1,
		/// <summary>
		/// 水平翻轉。
		/// </summary>
		Rotate0FlipX = 2,
		/// <summary>
		/// 旋轉 180 度。
		/// </summary>
		Rotate180 = 3,
		/// <summary>
		/// 旋轉 180 度，並水平翻轉。
		/// </summary>
		Rotate180FlipX = 4,
		/// <summary>
		/// 順時鐘旋轉 270 度，再垂直翻轉。
		/// </summary>
		Rotate270FlipY = 5,
		/// <summary>
		/// 順時鐘旋轉 270 度。
		/// </summary>
		Rotate270 = 6,
		/// <summary>
		/// 順時鐘旋轉 90 度，再垂直翻轉。
		/// </summary>
		Rotate90FlipY = 7,
		/// <summary>
		/// 順時鐘旋轉 90 度。
		/// </summary>
		Rotate90 = 8,
	}
	#endregion
}
